﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Reflection;

namespace GU.WebERP.Core.AjaxFx
{
    /// <summary>
    /// 存放标记有 AjaxFxClassAttribute 特性的类的相关信息
    /// </summary>
    public class AjaxFxClassInfo
    {
        /// <summary>
        /// 类编码
        /// </summary>
        public string Code
        {
            get;
            set;
        }

        /// <summary>
        /// 完整类名
        /// </summary>
        public string Name
        {
            get;
            set;
        }

        /// <summary>
        /// 描述
        /// </summary>
        public string Description
        {
            get;
            set;
        }

        /// <summary>
        /// 类 Type
        /// </summary>
        public Type ClassType
        {
            get;
            private set;
        }

        /// <summary>
        /// 类里面所有标记有 AjaxFxMethodAttribute 的方法
        /// </summary>
        internal Dictionary<string, AjaxFxMethodInfo> Methods
        {
            get;
            set;
        }

        /// <summary>
        /// 存放标记有 AjaxFxClassAttribute 特性的类的相关信息
        /// </summary>
        /// <param name="type">类 Type</param>
        /// <param name="code">类编码</param>
        /// <param name="description">描述</param>
        public AjaxFxClassInfo(Type type, string code, string description)
        {
            this.ClassType = type;
            this.Code = code;
            this.Description = description;

            // 收集类中标记有 AjaxFxMethodAttribute 的方法
            CollectMethods(type);
        }

        /// <summary>
        /// 调用类的指定方法
        /// </summary>
        /// <param name="code">方法编码</param>
        /// <param name="context">Http 上下文</param>
        /// <returns></returns>
        public AjaxFxRspJson CallMethod(string code, HttpContext context)
        {
            if (string.IsNullOrEmpty(code))
            {
                return null;
            }

            if (this.Methods.ContainsKey(code))
            {
                object obj = System.Activator.CreateInstance(this.ClassType);
                return (AjaxFxRspJson)this.Methods[code].Method.Invoke(obj, new object[] { context });
            }

            return null;
        }

        /// <summary>
        /// 收集类中标记有 AjaxFxMethodAttribute 的方法
        /// </summary>
        private void CollectMethods(Type type)
        {
            this.Methods = new Dictionary<string, AjaxFxMethodInfo>();
            MethodInfo[] infos = type.GetMethods();
            if (infos != null && infos.Length > 0)
            {
                foreach (var info in infos)
                {
                    object[] attribs = info.GetCustomAttributes(typeof(AjaxFxMethodAttribute), false);
                    if (attribs != null && attribs.Length > 0)
                    {
                        AjaxFxMethodAttribute attrib = (AjaxFxMethodAttribute)attribs[0];
                        if (this.Methods.ContainsKey(attrib.Code))
                        {
                            throw new Exception("类 " + type.FullName + " 中，方法 Code:" + attrib.Code + " 已被其它函数使用，请确认");
                        }
                        else
                        {
                            var method = new AjaxFxMethodInfo()
                            {
                                Code = attrib.Code,
                                Name = attrib.Name ?? info.Name,
                                MustSession = attrib.MustSession,
                                Description = attrib.Description,
                                Log = attrib.Log,
                                Method = info
                            };
                            this.Methods.Add(attrib.Code.ToLower(), method);
                        }
                    }
                }
            }
        }
    }
}
